package com.wjjun.base.widget.decoration

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ItemDecoration
import com.wjjun.base.ui.viewmodel.BaseItemViewModel
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter


/**
 * 可以控制分割线和间距的Decoration
 */
open class ViewModelItemDecoration(context: Context) :
    ItemDecoration() {
    private val dividerPaint = Paint()
    private val density = context.resources.displayMetrics.density

    /**
     * 获取item的间距
     */
    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        val manager = parent.layoutManager ?: return
        val position = parent.getChildAdapterPosition(view)
        val itemCount = parent.adapter!!.itemCount
        if (position < 0 || position > itemCount) {
            return
        }
        if (parent.adapter == null || parent.adapter !is BindingRecyclerViewAdapter<*>) {
            return
        }
        val adapter = parent.adapter as BindingRecyclerViewAdapter<*>
        val itemViewModel = adapter.getAdapterItem(position)
        if (itemViewModel !is BaseItemViewModel<*>) {
            return
        }
        val dividerHeight = dip2px(itemViewModel.getBtmDividerHeight(position, itemCount))

        if (manager is GridLayoutManager) {
            val span = manager.spanCount
            //同一行的最尾部来计算行数的时候与这一行的其他数计算行数不一样 所以总数-1
            val totalLine = (itemCount - 1) / span
            if (totalLine < 1) {
                return
            }
            //网格布局
            if (view.layoutParams is GridLayoutManager.LayoutParams) {
                val layoutParams = view.layoutParams as GridLayoutManager.LayoutParams
                itemViewModel.setOutRect(
                    outRect,
                    position,
                    itemCount,
                    layoutParams.spanIndex,
                    span
                )
            }
            if (position / span < totalLine) {
                outRect.bottom += dividerHeight
            }
        } else {
            itemViewModel.setOutRect(outRect, position, itemCount, 0, 0)
            //排除第一行和最后一行 其他行都加空隙
            outRect.bottom += dividerHeight
        }
    }

    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        if (parent.adapter == null || parent.adapter !is BindingRecyclerViewAdapter<*>) {
            return
        }

        val adapter = parent.adapter as BindingRecyclerViewAdapter<*>
        for (i in 0 until parent.childCount) {
            val view = parent.getChildAt(i)
            val index = parent.getChildAdapterPosition(view)
            if (index < 0) {
                continue
            }
            val itemViewModel = adapter.getAdapterItem(index)
            if (itemViewModel !is BaseItemViewModel<*>) {
                continue
            }
            //间距
            val margin =
                dip2px(itemViewModel.getBtmDividerHorizontalMargin(index, adapter.itemCount))
            //绘制分割线
            val dividerHeight = dip2px(itemViewModel.getBtmDividerHeight(index, adapter.itemCount))
            //分割线颜色
            dividerPaint.color = itemViewModel.getDividerColor()

            if (dividerHeight > 0 || margin > 0) {
                c.drawRect(
                    (view.left + margin).toFloat(),
                    view.bottom.toFloat(),
                    (view.right - margin).toFloat(),
                    (view.bottom + dividerHeight).toFloat(),
                    dividerPaint
                )
            }
        }
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    fun dip2px(dpValue: Double): Int {
        return (dpValue * density + 0.5f).toInt()
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    fun dip2px(dpValue: Int): Int {
        return (dpValue * density + 0.5f).toInt()
    }

}
